//+------------------------------------------------------------------+
//|                                        MarketConditionIndicator.mq5 |
//|                                          Copyright 2024            |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024"
#property link ""
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0

// 市场状态分析设置
input ENUM_TIMEFRAMES MarketAnalysisTimeframe = PERIOD_M5;  // 市场分析时间框架
input int TrendPeriod = 200;             // 趋势判断周期
input int VolatilityPeriod = 20;         // 波动率计算周期
input bool UseADX = true;                // 使用ADX指标
input int ADXPeriod = 14;                // ADX周期
input double ADXThreshold = 25;          // ADX阈值

// 市场状态枚举
enum MARKET_CONDITION {
    RANGING = 1,         // 震荡市
    TRENDING = 2,        // 趋势市
    VOLATILE = 3         // 高波动
};

// 全局变量
MARKET_CONDITION g_currentMarketCondition = RANGING;
MARKET_CONDITION g_previousMarketCondition = RANGING;
int g_lastStateChangeBar = 0;

// 指标句柄
int ma200Handle;
int ma50Handle;
int ma20Handle;
int adxHandle;
int rsiHandle;
int bbHandle;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                           |
//+------------------------------------------------------------------+
int OnInit()
{
    // 初始化市场分析指标
    Print("开始初始化市场分析指标...");
    ma200Handle = iMA(_Symbol, MarketAnalysisTimeframe, TrendPeriod, 0, MODE_SMA, PRICE_CLOSE);
    ma50Handle = iMA(_Symbol, MarketAnalysisTimeframe, 50, 0, MODE_SMA, PRICE_CLOSE);
    ma20Handle = iMA(_Symbol, MarketAnalysisTimeframe, 20, 0, MODE_SMA, PRICE_CLOSE);
    adxHandle = iADX(_Symbol, MarketAnalysisTimeframe, ADXPeriod);
    rsiHandle = iRSI(_Symbol, MarketAnalysisTimeframe, 14, PRICE_CLOSE);
    bbHandle = iBands(_Symbol, MarketAnalysisTimeframe, 20, 2, 0, PRICE_CLOSE);
    
    // 检查指标句柄是否创建成功
    if(ma200Handle == INVALID_HANDLE || ma50Handle == INVALID_HANDLE || 
       ma20Handle == INVALID_HANDLE || adxHandle == INVALID_HANDLE || 
       rsiHandle == INVALID_HANDLE || bbHandle == INVALID_HANDLE) {
        Print("指标初始化失败 - 错误代码: ", GetLastError());
        return INIT_FAILED;
    }
    Print("市场分析指标初始化成功");
    
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                                |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
    UpdateMarketCondition();
    return(rates_total);
}

//+------------------------------------------------------------------+
//| 更新市场状态                                                       |
//+------------------------------------------------------------------+
void UpdateMarketCondition() {
    double adx[], plusDI[], minusDI[];
    ArraySetAsSeries(adx, true);
    ArraySetAsSeries(plusDI, true);
    ArraySetAsSeries(minusDI, true);
    
    // 获取ADX值
    if(CopyBuffer(adxHandle, 0, 0, 2, adx) <= 0) return;
    if(CopyBuffer(adxHandle, 1, 0, 2, plusDI) <= 0) return;
    if(CopyBuffer(adxHandle, 2, 0, 2, minusDI) <= 0) return;
    
    // 计算波动率
    double volatility = GetCurrentVolatility();
    double avgVolatility = GetAverageVolatility();
    
    // 计算趋势持续性
    int trendCount = 0;
    double close[];
    ArraySetAsSeries(close, true);
    if(CopyClose(_Symbol, MarketAnalysisTimeframe, 0, 4, close) <= 0) return;
    
    for(int i = 0; i < 3; i++) {
        if(close[i] > close[i+1]) trendCount++;
        else trendCount--;
    }
    
    // 保存前一个市场状态
    g_previousMarketCondition = g_currentMarketCondition;
    
    // 判断市场状态
    if(adx[0] > ADXThreshold * 1.2 && MathAbs(trendCount) >= 2) {
        g_currentMarketCondition = TRENDING;
    }
    else if(volatility > avgVolatility * 1.8) {
        g_currentMarketCondition = VOLATILE;
    }
    else {
        g_currentMarketCondition = RANGING;
    }
    
    // 获取当前时间和价格
    datetime currentTime = TimeCurrent();
    double currentPrice = iClose(_Symbol, MarketAnalysisTimeframe, 0);
    
    // 检查市场状态是否发生变化
    if(g_currentMarketCondition != g_previousMarketCondition) {
        int currentBar = iTime(_Symbol, MarketAnalysisTimeframe, 0);
        if(currentBar - g_lastStateChangeBar >= 5) {
            // 在状态转换时绘制箭头
            string arrowName = "状态转换_" + TimeToString(currentTime);
            color arrowColor;
            int arrowCode;
            string stateLabel;
            
            // 设置箭头颜色和样式
            if(g_currentMarketCondition == TRENDING) {
                if(plusDI[0] > minusDI[0]) {
                    arrowColor = C'144,238,144'; // 淡绿色
                    arrowCode = 241; // 向上箭头
                    stateLabel = "趋势向上";
                } else {
                    arrowColor = C'255,182,193'; // 淡红色
                    arrowCode = 242; // 向下箭头
                    stateLabel = "趋势向下";
                }
            } else if(g_currentMarketCondition == VOLATILE) {
                arrowColor = C'255,218,185'; // 淡橙色
                arrowCode = 159; // 菱形
                stateLabel = "高波动";
            } else {
                arrowColor = C'173,216,230'; // 淡蓝色
                arrowCode = 159; // 菱形
                stateLabel = "震荡";
            }
            
            // 创建箭头对象
            if(!ObjectCreate(0, arrowName, OBJ_ARROW, 0, currentTime, currentPrice)) {
                Print("创建状态转换箭头失败 - 错误代码: ", GetLastError());
            } else {
                ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, arrowCode);
                ObjectSetInteger(0, arrowName, OBJPROP_COLOR, arrowColor);
                ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 2);
                ObjectSetInteger(0, arrowName, OBJPROP_BACK, false);
                ObjectSetInteger(0, arrowName, OBJPROP_SELECTABLE, false);
                ObjectSetInteger(0, arrowName, OBJPROP_SELECTED, false);
                ObjectSetInteger(0, arrowName, OBJPROP_HIDDEN, true);
                ObjectSetInteger(0, arrowName, OBJPROP_ZORDER, 0);
                
                // 添加状态标签
                string labelName = arrowName + "_标签";
                if(!ObjectCreate(0, labelName, OBJ_TEXT, 0, currentTime, currentPrice)) {
                    Print("创建状态标签失败 - 错误代码: ", GetLastError());
                } else {
                    ObjectSetString(0, labelName, OBJPROP_TEXT, stateLabel);
                    ObjectSetInteger(0, labelName, OBJPROP_COLOR, arrowColor);
                    ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, 8);
                    ObjectSetString(0, labelName, OBJPROP_FONT, "Arial");
                    ObjectSetInteger(0, labelName, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER);
                    ObjectSetInteger(0, labelName, OBJPROP_SELECTABLE, false);
                    ObjectSetInteger(0, labelName, OBJPROP_SELECTED, false);
                    ObjectSetInteger(0, labelName, OBJPROP_HIDDEN, true);
                    ObjectSetInteger(0, labelName, OBJPROP_ZORDER, 0);
                }
            }
            
            Print("市场状态发生变化 - 从", 
                  g_previousMarketCondition == RANGING ? "震荡市" : 
                  g_previousMarketCondition == TRENDING ? "趋势市" : "高波动",
                  " 变为 ",
                  g_currentMarketCondition == RANGING ? "震荡市" : 
                  g_currentMarketCondition == TRENDING ? "趋势市" : "高波动");
            
            g_lastStateChangeBar = currentBar;
        }
    }
    
    // 绘制状态覆盖区域
    string rectName = "市场状态_" + TimeToString(g_lastStateChangeBar);
    color rectColor;
    
    // 设置覆盖区域颜色
    if(g_currentMarketCondition == TRENDING) {
        if(plusDI[0] > minusDI[0]) {
            rectColor = C'144,238,144'; // 淡绿色
        } else {
            rectColor = C'255,182,193'; // 淡红色
        }
    } else if(g_currentMarketCondition == VOLATILE) {
        rectColor = C'255,218,185'; // 淡橙色
    } else {
        rectColor = C'173,216,230'; // 淡蓝色
    }
    
    // 创建或更新矩形对象
    if(!ObjectCreate(0, rectName, OBJ_RECTANGLE, 0, g_lastStateChangeBar, 0, currentTime, 0)) {
        Print("创建状态覆盖区域失败 - 错误代码: ", GetLastError());
    } else {
        ObjectSetInteger(0, rectName, OBJPROP_COLOR, rectColor);
        ObjectSetInteger(0, rectName, OBJPROP_STYLE, STYLE_SOLID);
        ObjectSetInteger(0, rectName, OBJPROP_WIDTH, 1);
        ObjectSetInteger(0, rectName, OBJPROP_FILL, true);
        ObjectSetInteger(0, rectName, OBJPROP_BACK, true);
        ObjectSetInteger(0, rectName, OBJPROP_SELECTABLE, false);
        ObjectSetInteger(0, rectName, OBJPROP_SELECTED, false);
        ObjectSetInteger(0, rectName, OBJPROP_HIDDEN, true);
        ObjectSetInteger(0, rectName, OBJPROP_ZORDER, 0);
    }
    
    // 更新状态文本
    string stateText = "市场状态: ";
    switch(g_currentMarketCondition) {
        case TRENDING:
            stateText += plusDI[0] > minusDI[0] ? "趋势向上" : "趋势向下";
            break;
        case VOLATILE:
            stateText += "高波动";
            break;
        default:
            stateText += "震荡";
    }
    
    // 创建或更新状态文本对象
    if(!ObjectCreate(0, "市场状态文本", OBJ_LABEL, 0, 0, 0)) {
        Print("创建状态文本失败 - 错误代码: ", GetLastError());
    } else {
        ObjectSetString(0, "市场状态文本", OBJPROP_TEXT, stateText);
        ObjectSetInteger(0, "市场状态文本", OBJPROP_XDISTANCE, 10);
        ObjectSetInteger(0, "市场状态文本", OBJPROP_YDISTANCE, 10);
        ObjectSetInteger(0, "市场状态文本", OBJPROP_COLOR, rectColor);
        ObjectSetInteger(0, "市场状态文本", OBJPROP_FONTSIZE, 10);
        ObjectSetString(0, "市场状态文本", OBJPROP_FONT, "Arial");
        ObjectSetInteger(0, "市场状态文本", OBJPROP_CORNER, CORNER_LEFT_UPPER);
        ObjectSetInteger(0, "市场状态文本", OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER);
        ObjectSetInteger(0, "市场状态文本", OBJPROP_SELECTABLE, false);
        ObjectSetInteger(0, "市场状态文本", OBJPROP_SELECTED, false);
        ObjectSetInteger(0, "市场状态文本", OBJPROP_HIDDEN, true);
        ObjectSetInteger(0, "市场状态文本", OBJPROP_ZORDER, 0);
    }
}

//+------------------------------------------------------------------+
//| 计算当前波动率                                                     |
//+------------------------------------------------------------------+
double GetCurrentVolatility() {
    double high[], low[];
    ArraySetAsSeries(high, true);
    ArraySetAsSeries(low, true);
    
    if(CopyHigh(_Symbol, MarketAnalysisTimeframe, 0, VolatilityPeriod, high) <= 0) {
        Print("获取最高价失败 - 错误代码: ", GetLastError());
        return 0;
    }
    if(CopyLow(_Symbol, MarketAnalysisTimeframe, 0, VolatilityPeriod, low) <= 0) {
        Print("获取最低价失败 - 错误代码: ", GetLastError());
        return 0;
    }
    
    double volatility = 0;
    for(int i = 0; i < VolatilityPeriod; i++) {
        volatility += MathAbs(high[i] - low[i]);
    }
    return volatility / VolatilityPeriod;
}

//+------------------------------------------------------------------+
//| 计算平均波动率                                                     |
//+------------------------------------------------------------------+
double GetAverageVolatility() {
    double high[], low[];
    ArraySetAsSeries(high, true);
    ArraySetAsSeries(low, true);
    
    if(CopyHigh(_Symbol, MarketAnalysisTimeframe, 0, VolatilityPeriod * 5, high) <= 0) {
        Print("获取长期最高价失败 - 错误代码: ", GetLastError());
        return 0;
    }
    if(CopyLow(_Symbol, MarketAnalysisTimeframe, 0, VolatilityPeriod * 5, low) <= 0) {
        Print("获取长期最低价失败 - 错误代码: ", GetLastError());
        return 0;
    }
    
    double sum = 0;
    for(int i = 0; i < VolatilityPeriod * 5; i++) {
        sum += MathAbs(high[i] - low[i]);
    }
    return sum / (VolatilityPeriod * 5);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // 清理所有图形对象
    ObjectsDeleteAll(0);
} 